#ifndef RETRIEVE_PCAP
#define RETRIEVE_PCAP
#endif
#define equal(a,b) ((a->BasicInfo).Ip.Dst==(b->BasicInfo).Ip.Dst)&&((a->BasicInfo).Ip.Src==(b->BasicInfo).Ip.Src)&&((a->BasicInfo).Port.Src==(b->BasicInfo).Port.Src)&&((a->BasicInfo).Port.Dst==(b->BasicInfo).Port.Dst)&&((a->BasicInfo).Protocol==(b->BasicInfo).Protocol)
char Format[100];

struct IP
{
    long Src;
    long Dst;
};

struct PORT
{
    int Src;
    int Dst;
};

struct FiveTuple
{
    struct IP Ip;    
    struct PORT Port;
    char Protocol;	//protocol in ip header
};

struct packet
{
    unsigned int captureLen;
    struct FiveTuple BasicInfo;
};

struct flow	// bi-directional flow
{
    unsigned int count;
    struct FiveTuple BasicInfo;
    unsigned int PKG_SIZE[5];
    struct flow *next;		// ptr for constructing flow list
};

// statistic for retrieve result
struct statistic
{
    long TotOfPkg;
    long TotOfReg;
    char filename[30];
};

struct type 
{
    char ProtocolName[10];
    struct type *next;
};

// skip n bytes in file
void skip(FILE *fp, int n)
{
    int i;
    for(i=0;i<n;i++)
        fgetc(fp);
}

// convert 1 byte in file to num 0~255
int convert(FILE *fp)
{
    char temp=fgetc(fp);
    int num=temp;
    return (num<0?num+256:num);
}

// convert 4bytes in file to uint
void process_4B_uint(FILE *fp, unsigned int *num)
{
    int i, temp;
    *num=0;
    for(i=0; i<4; i++)
    {
        temp=convert(fp);
        (*num)+=(unsigned int)(temp)<<(8*i);
    }
}

//convert 2 bytes in file to ushort
void process_2B_ushort(FILE *fp, unsigned short *num)
{
    int i, temp;
    *num=0;
    for(i=0; i<2; i++)
    {
        temp=convert(fp);
        (*num)+=(unsigned short)(temp)<<(8*i);
    }
}
// process the port area, convert to ushort
void process_port(FILE *fp, unsigned short *port)
{
    unsigned char ch[2];
    unsigned short subPort[2];
    ch[0]=fgetc(fp);
    //    printf("ch[0]=%d,",ch[0]);
    ch[1]=fgetc(fp);
    //   printf("ch[1]=%d\n",ch[1]);
    subPort[0]=(unsigned short)(ch[0])<<8;
    subPort[1]=(unsigned short)(ch[1]);
    *port=subPort[0]|subPort[1];
    //  printf("Port:%d\n",*port);
    // int i;
    //  scanf("%d",&i);
}
//process the ip area, convert to ulong
void process_ip(FILE *fp, unsigned long *ip)
{
    unsigned char ch;
    unsigned long subIP[4];
    int i;
    // printf("IP:");
    for( i=0; i<4; i++)
    {
        ch=fgetc(fp);
        //     printf("%d.",ch);
        subIP[i]=(unsigned long)(ch<<(8*i));
    }
    //  printf("\n");
    //  scanf("%d",&i);
    *ip=subIP[0]|subIP[1]|subIP[2]|subIP[3];
}
void getClass(int MasterID,int ViceID,char Class[50])
{
    int combination=100*MasterID+ViceID; 
    if(combination>100&&combination<200)
    {
        switch(combination)
        {
            case 101://HTTP
            case 102://HTTPS
            case 103://HTTP STOP-CONTINUE TRANSMISSION
                strcpy(Class,"\"WEB\"");
                break;
            case 104://FTP
                strcpy(Class,"\"FTP\"");
                break;
            case 105://SMTP
            case 106://POP3
            case 107://IMAP
                //case 108://TFTP
            case 109://NNTP
                strcpy(Class,"\"MAIL\\NEWS\"");
                break;
            case 110://NTP
            case 111://ICMP
                //case 112://RADIUS/TRACACS
            case 113://BGP
            case 114://DHCP
            case 115://DNS
            case 116://SMB/SAMBA
            case 117://SNMP
            case 118://SNTP
                strcpy(Class,"\"SERVICES\"");
                break;
                //case 119://RPC
                //case 120://SOCKS
                //case 121://TLS/SSL
        }
        return;
    }
    if(combination>200&&combination<300)
    {
        strcpy(Class,"\"CHAT\"");
        return;
    }
    if(combination>300&&combination<400)
    {
        strcpy(Class,"\"GAMES\"");
        return;
    }
    if(combination>400&&combination<500)
    {
        strcpy(Class,"\"STREAMING\"");
        return;
    }
    if(combination>500&&combination<600)
    {
        strcpy(Class,"\"VOIP\"");
        return;
    }
    if(combination>600&&combination<700)
    {
        strcpy(Class,"\"P2P\"");
        return;
    }
    strcpy(Class,"\"UNKNOWN\"");
    return;
}
char* timeTransform(unsigned long time)
{
    memset(Format,0,100);
    int hour=time/3600;
    int min=(time-hour*3600)/60;
    int sec=time-hour*3600-min*60;
    if(hour>0)
    {
        sprintf(Format,"%dh%dmin%ds",hour,min,sec);
        return Format;
    }
    else
        if(min>0)
        {
            sprintf(Format,"%dmin%ds",min,sec);
            return Format;
        }
        else
        {
            sprintf(Format,"%ds",sec);
            return Format;
        }
}
char* sizeTransform(unsigned long long size)
{
    memset(Format,0,100);
    int GB=size/1024/1024/1024;
    int MB=(size-GB*1024*1024*1024)/1024/1024;
    int KB=(size-GB*1024*1024*1024-MB*1024*1024)/1024;
    int  B=(size-GB*1024*1024*1024-MB*1024*1024-KB*1024);
    if(GB>0)
    {
        sprintf(Format,"%.3fGB",((double)size)/1024/1024/1024);
        return Format;
    }
    else
        if(MB>0)
        {
            sprintf(Format,"%.3fMB",((double)size)/1024/1024);
            return Format;
        }
        else
            if(KB>0)
            {
                sprintf(Format,"%.3fKB",((double)size)/1024);
                return Format;
            }
            else
            {
                sprintf(Format,"%dB",size);
                return Format;
            }
}
